package com.ews.onlineexchange.shiro;

import com.ews.onlineexchange.model.User;
import com.ews.onlineexchange.service.UserService;
import com.ews.onlineexchange.util.Encodes;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.credential.Sha256CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.util.SimpleByteSource;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Startup;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.persistence.EntityManager;
import java.security.Principal;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * @program: SdewsOnlineExchange
 * @description:
 * @author: wangchangqing
 * @create: 2020-12-28 17:08
 **/
@Named
public class OnlineExchangeRealm extends AuthorizingRealm {
    private final static int TIMEOUT = 120 * 60 * 1000;
    @Inject
    UserService userService;

    /**
     * 获取权限信息 加载用户的角色和权限数据
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        User user = (User)principals.getPrimaryPrincipal();
        String roleStr = user.getRoles();
        String[] roleArray = roleStr == null ? new String[]{} : roleStr.split("、");
        Set<String> roles = new HashSet<>(Arrays.asList(roleArray));
//        if(roles.size() == 0){
//            roles.add("admin");
//            roles.add("credentialManager");
//            roles.add("businessManager");
//        }
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(roles);
        //authorizationInfo.setStringPermissions(permissions);

        return authorizationInfo;
    }

    /**
     * 获取认证信息 根据用户输入的口令查找对应用户的认证数据(密文密码+盐).
     * @param authcToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {

        SecurityUtils.getSubject().getSession().setTimeout(TIMEOUT);
        System.out.println(SecurityUtils.getSubject().getSession().getTimeout());
        String username = StringUtils.trim((String) authcToken.getPrincipal());
        if (StringUtils.isEmpty(username)) {
            throw new AuthenticationException();
        }
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;


        User user = userService.findByUsername(token.getUsername());
        if (user != null) {
            byte[] salt = Encodes.decodeHex(user.getShiroPwd().substring(0, 16));
            return new SimpleAuthenticationInfo(user, user.getShiroPwd().substring(16), ByteSource.Util.bytes(salt), getName());
        } else {
            return null;
        }
    }
    @PostConstruct
    public void initCredentialsMatcher() {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(UserService.HASH_ALGORITHM);
        matcher.setHashIterations(UserService.HASH_INTERATIONS);
        setCredentialsMatcher(matcher);
    }

    /**
     * 清空用户关联权限认证，待下次使用时重新加载
     */
    public void clearCachedAuthorizationInfo(String principal) {
        SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
        clearCachedAuthorizationInfo(principals);
    }

    /**
     * 清空所有关联认证
     */
    public void clearAllCachedAuthorizationInfo() {
        Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
        if (cache != null) {
            for (Object key : cache.keys()) {
                cache.remove(key);
            }
        }
    }
    public static void main(String[] args) {
        UserService userService = new UserService();
        System.out.println(userService.entryptPassword("Zzrj@8309899"));



    }
}
